Android 输入框(EditText)的输入限制,数字英文邮箱,可见\隐藏切换,踩过的坑! |
您所在的位置:网站首页 › walkman apk限制代码 › Android 输入框(EditText)的输入限制,数字英文邮箱,可见\隐藏切换,踩过的坑! |
目录 一、输入框的输入限制 1.在xml文件里通过设置属性限制输入 2.在代码里动态设置输入限制 二、密码可见性切换和遇到的坑 最近做到了登录注册模块的各种输入判定,监听等等,因为需求上的需要,还是搞了好一会儿,今天在这总结一下。 常规的输入框输入需求有纯数字,字母,混合输入,邮箱,键盘默认打开数字键盘,密码可见性,键盘的收起弹出等等。 一、输入框的输入限制 1.在xml文件里通过设置属性限制输入1.inputType 例如:输入纯数字,则只需要在editText控件属性下加一句:android:inputType="number" 常用的属性有: android:inputType="none"输入普通字符 android:inputType="text" 输入普通字符 android:inputType="textCapCharacters" 输入普通字符 android:inputType="textCapWords" 单词首字母大小 android:inputType="textCapSentences" 仅第一个字母大小 android:inputType="textAutoCorrect" 前两个自动完成 android:inputType="textAutoComplete" 前两个自动完成 android:inputType="textMultiLine" 多行输入 android:inputType="textImeMultiLine" 输入法多行(不一定支持) android:inputType="textNoSuggestions" 不提示 android:inputType="textUri" URI格式 android:inputType="textEmailAddress" 电子邮件地址格式 android:inputType="textEmailSubject" 邮件主题格式 android:inputType="textShortMessage" 短消息格式 android:inputType="textLongMessage" 长消息格式 android:inputType="textPersonName" 人名格式 android:inputType="textPostalAddress" 邮政格式 android:inputType="textPassword" 密码格式 android:inputType="textVisiblePassword" 密码可见格式 android:inputType="textWebEditText"作为网页表单的文本格式 android:inputType="textFilter" 文本筛选格式 android:inputType="textPhonetic" 拼音输入格式 android:inputType="number" 数字格式 android:inputType="numberSigned" 有符号数字格式 android:inputType="numberDecimal" 可以带小数点的浮点格式 android:inputType="phone" 拨号键盘 android:inputType="datetime" 日期+时间格式 android:inputType="date" 日期键盘 android:inputType="time" 时间键盘 这个属性,配置后键盘会有不同的展现方式,根据手机的键盘软件自适应,有些属性会限制输入,有些则不会,例如number会限制你只能输入数字,textPassword会把输入的内容占位但不可见,就和输入QQ密码一样。 2.在xml里面设置digits属性 android:digits="[email protected]#$qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"那么他就只能输入以上digits里面的内容. 2.在代码里动态设置输入限制1.通过setKeyListener进行限制(kotlin) editText.keyListener = DigitsKeyListener.getInstance("qwertyuiopasdfghjklzx"+ "cvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890\\[email protected]#$^")eg1:为啥会有两个\\呢,因为\是转义字符,所以第一个是拿来转义后面的\的。不了解转义字符的可以看下面链接: 什么是转义字符?转义字符有哪些?为什么使用转义字符?_程序猿!=程序员的博客-CSDN博客_转义字符接上文转义字符相关内容学习。 这个是写的正则表达式,用来判断邮箱格式的,返回的布尔值代表格式是否正确 3.通过InputFilter来过滤输入 val typeFilter = InputFilter { source, _, _, _, _, _ -> // p: Pattern = Pattern.compile("[0-9a-zA-Z|\u4e00-\u9fa5]+") //限制输入中英文,数字 val p: Pattern = Pattern.compile("[0-9a-zA-Z|[email protected]#$]+")//限制输入数字英文和部分特殊字符 val m: Matcher = p.matcher(source.toString()) if (!m.matches()) "" else null } searchEdit?.filters = arrayOf(typeFilter, InputFilter.LengthFilter(10))eg:上面的代码是kotlin哈,他其实是复写了里面的filter方法,这里我把java代码也粘出来。 InputFilter typeFilter = new InputFilter() { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { Pattern p = Pattern.compile("[0-9a-zA-Z|\u4e00-\u9fa5]+"); Matcher m = p.matcher(source.toString()); if (!m.matches()) return ""; return null; } }; //如果要限制输入字数,数组中加上new InputFilter.LengthFilter(maxLength) searchEdit.setFilters(new InputFilter[]{typeFilter, new InputFilter.LengthFilter(10)});解析:setFilters() 方法,传入的参数是一个filter列表,在上面代码中,为啥我后面又补了一个InputFilter.LengthFilter(10)呢,因为如果不加上这个,会让xml布局里面的maxLength属性失效,因为在TextVIew的源码的构造方法中有一个变量maxLength它对应xml中属性android:maxLength,如果有值就赋值给变量maxLength,如果大于等于0,就调用setFilters(),传入一个InputFilter.LengthFilter。但是我们又在自己的代码中又setFilters了,就把以前的属性替换掉了,所以,要在这儿补上去哦! TextView源码: public TextView( Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); ... int maxlength = -1; ... case com.android.internal.R.styleable.TextView_maxLength: maxlength = a.getInt(attr, -1); break; ... if (maxlength >= 0) { setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) }); } else { setFilters(NO_FILTERS); } ... }关于Patter和Matcher的用法:我爱学Java之Pattern和Matcher用法_Java.Sheng的博客-CSDN博客Java正则表达式通过java.util.regex包下的Pattern和Matcher类实现Pattern类用于创建一个正则表达式,也可以说是创建一个匹配模式,可以通过两个静态方法创建:compile(String regex)和compile(String regex,int flags),其中regex是正则表达式,flags为可选模式(如:Pattern.CASE_INSENSITIVE 忽 4.代码里通过设置InputType 这个就和xml里属性设置差不多,不过代码里更加灵活。下面的代码就是动态设置输入内容可见/不可见,就是类似于QQ密码的那个眼睛图标的功能。 private fun setEditPassword(editText: EditText, passwordVisible: Boolean) { if (passwordVisible) { //选择状态 显示明文--设置为可见的密码 editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD } else { //默认状态显示密码--设置文本 要一起写才能起作用 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD } }以上就是输入限制的一些方法,可以根据需求打一套组合拳,但是有些方法也会有冲突导致失效,这时候就可以去看看源码。 二、密码可见性切换和遇到的坑1.使用setKeyListner和inputType组合使用的冲突: 需求:1.对密码输入做限制2.密码可点击眼睛图标进行可见、隐藏。 限制代码 editText.keyListener = DigitsKeyListener.getInstance("qwertyuiopasdfghjklzx"+ "cvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890\\[email protected]#$^")点击事件进行密码隐藏 private fun setEditPassword(editText: EditText, passwordVisible: Boolean) { if (passwordVisible) { //选择状态 显示明文--设置为可见的密码 editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD } else { //默认状态显示密码--设置文本 要一起写才能起作用 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD } }冲突表现:点击图标进行切换后,原来的keyListener设置的限制失效,可以输入任意字符 原因看源码:在keyListener里, public void setKeyListener(KeyListener input) { mListenerChanged = true; setKeyListenerOnly(input); fixFocusableAndClickableSettings(); if (input != null) { createEditorIfNeeded(); setInputTypeFromEditor(); } else { if (mEditor != null) mEditor.mInputType = EditorInfo.TYPE_NULL; } InputMethodManager imm = getInputMethodManager(); if (imm != null) imm.restartInput(this); }看最后两行,这儿会将软键盘重置了,故使用的软键盘是其自己getInputType方法得到的数字键盘模式。 他的getInputType方法源码: /** * Returns the input type for the listener. */ public int getInputType() { int contentType; if (mNeedsAdvancedInput) { contentType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL; } else { contentType = InputType.TYPE_CLASS_NUMBER; if (mSign) { contentType |= InputType.TYPE_NUMBER_FLAG_SIGNED; } if (mDecimal) { contentType |= InputType.TYPE_NUMBER_FLAG_DECIMAL; } } return contentType; }接下来: public void setInputType(int type) { final boolean wasPassword = isPasswordInputType(getInputType()); ......有点多我删了,看下面 InputMethodManager imm = getInputMethodManager(); if (imm != null) imm.restartInput(this); }看最后两行,这儿setInputType方法将软键盘重置成全键盘模式,前面设置的DigitsKeyListener就失效了,变成新的。 解决办法1:在setEditPassword这个方法设置密码可见\隐藏后,再设置限制,这样就不会失效了,相当于每次点击图标切换,都会对输入框进行一次设定,相比于输入框的一些监听事件啊,这种操作也可以接受。(这个方法可能会因为inputType变化频繁导致部分手机的键盘切两次哦,所以这个方法不大完美!) 解决方法2:新的组合拳!!!InputFilter+setInputType 代码:将上面的setKeyListener干掉,用下面的方法限制,就完美结局了,有maxLength记得补上哦~ val typeFilter = InputFilter { source, start, end, dest, dstart, dend -> //限制只能输入中文,英文,数字 // val p: Pattern = Pattern.compile("[0-9a-zA-Z|\u4e00-\u9fa5]+") val p: Pattern = Pattern.compile("[0-9a-zA-Z|[email protected]#$]+") val m: Matcher = p.matcher(source.toString()) if (!m.matches()) "" else null } editText?.filters = arrayOf(typeFilter, InputFilter.LengthFilter(10))这块的总结就到这儿了,有疑问的欢迎评论区讨论哈,有不对的地方望大佬指教! |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |